

#include <efd/DefaultInitializeMemoryManager.h>
EE_USE_DEFAULT_ALLOCATOR;

#include "lua.h"
#include "Engine.h"


extern int luaopen_gamebryo(lua_State*);

int luaopen_Engine(lua_State* L )
{
	return luaopen_gamebryo(L);
}

//---------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------

string NiObjectNET_GetName( NiObjectNET* pObj )
{
	string n = pObj->GetName();
	return n;
}

void NiObjectNET_SetName( NiObjectNET* pObj, string name )
{
	pObj->SetName(name.c_str());
}

//--------------------------------------------------------------------------------------------------------

NiAVObject* NiAVObject_GetObjectByName( NiAVObject* pObj, string name )
{
	return pObj->GetObjectByName(name.c_str());
}

//--------------------------------------------------------------------------------------------------------
void NiAVObject_UpdateAll( NiAVObject*This, float fTime )
{
	NiMeshUpdateProcess kUpdateProcess;
	kUpdateProcess.SetTime(fTime);
	kUpdateProcess.SetUpdateControllers(true);
	kUpdateProcess.SetSubmitModifiers(true);

	This->Update(kUpdateProcess);
	This->UpdateProperties();
	This->UpdateEffects();
}

NiNode* NiAVObject_ToNiNode( NiAVObject* pObj )
{
	return NiDynamicCast(NiNode, pObj);
}

NiTerrain* NiAVObject_ToNiTerrain( NiAVObject* pObj )
{
	return NiDynamicCast(NiTerrain, pObj);
}

void NiCamera_LookAtObject( NiCamera* This, NiAVObject* target, double hori, double vert, double dist )
{
	NiPoint3 pt = target->GetWorldTranslate();
	NiCamera_LookAtWorldPoint( This, pt, hori, vert, dist);
}

void NiCamera_LookAtWorldPoint( NiCamera* This, NiPoint3& pt, double hori, double vert, double dist )
{
	if (dist < 0.001 || fabs(vert)>85.0)
		return;

	//NiPoint3 loc = WorldView::Calc(vert, hori, dist,  pt);

	const double pi = 3.14159265358979323846;
	double z = tan(vert*pi/180.0);
	double y = sin(hori*pi/180.0);
	double x = cos(hori*pi/180.0);

	NiPoint3 loc(x,y,z);
	loc.Unitize();
	loc *= dist;
	loc += pt;

	This->SetTranslate(loc);
	This->Update(0);
	This->LookAtWorldPoint(pt, NiPoint3(0, 0, 1));
	This->Update(0);
}

static bool bInit = false;
void InitEngine()
{
	if (!bInit)
	{
		bInit = true;
		NiInit();
	}
}

void ReleaseEngine()
{
	if (bInit)
	{
		bInit=false;
		NiShutdown();
	}
}

void SetMemoryLog( bool bOn )
{
	using namespace efd;
	if( MemTracker::Get() )
		MemTracker::Get()->SetWriteToLog(bOn);
}

BOOL __stdcall DllMain( HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved )
{
	switch (dwReason)
	{
	case DLL_PROCESS_ATTACH:
		//InitEngine();
		break;

	case DLL_PROCESS_DETACH:
		//ReleaseEngine();
		break;

	case DLL_THREAD_ATTACH:
		break;

	case DLL_THREAD_DETACH:
		break;
	}

	return (TRUE);

}

